home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / gfx / conv / dumpdtanim012.lha / dumpdtanim / dumpdtanim.c < prev    next >
C/C++ Source or Header  |  1996-12-12  |  40KB  |  1,285 lines

  1.  
  2.  
  3. /*
  4. **
  5. **  $VER: dumpdtanim.c 1.2 (11.12.96)
  6. **  dumpdtanim 1.0
  7. **
  8. **  main file
  9. **
  10. **  (C) Copyright 1996 by Roland 'Gizzy' Mainz
  11. **          All Rights Reserved
  12. **
  13. */
  14.  
  15.  
  16. /* amiga includes */
  17. #include <exec/types.h>
  18. #include <exec/memory.h>
  19. #include <exec/execbase.h>
  20. #include <exec/libraries.h>
  21. #include <dos/dos.h>
  22. #include <dos/dosextens.h>
  23. #include <datatypes/datatypes.h>
  24. #include <datatypes/datatypesclass.h>
  25. #include <datatypes/soundclass.h>
  26. #include <datatypes/pictureclass.h>
  27. #include <datatypes/animationclass.h>
  28. #include <workbench/workbench.h>
  29.  
  30. /* amiga prototypes */
  31. #include <clib/macros.h>
  32. #include <clib/exec_protos.h>
  33. #include <clib/dos_protos.h>
  34. #include <clib/iffparse_protos.h>
  35. #include <clib/icon_protos.h>
  36. #include <clib/graphics_protos.h>
  37. #include <clib/intuition_protos.h>
  38. #include <clib/datatypes_protos.h>
  39. #include <clib/dtclass_protos.h>
  40. #include <clib/alib_protos.h>
  41.  
  42. /* amiga pragmas */
  43. #include <pragmas/exec_pragmas.h>
  44. #include <pragmas/dos_pragmas.h>
  45. #include <pragmas/iffparse_pragmas.h>
  46. #include <pragmas/icon_pragmas.h>
  47. #include <pragmas/graphics_pragmas.h>
  48. #include <pragmas/intuition_pragmas.h>
  49. #include <pragmas/datatypes_pragmas.h>
  50. #include <pragmas/dtclass_pragmas.h>
  51.  
  52. /* ansi includes */
  53. #include <string.h>
  54.  
  55. /*****************************************************************************/
  56.  
  57. /* IFF FILM ID */
  58. #ifndef ID_FILM
  59. #define ID_FILM MAKE_ID( 'F', 'I', 'L', 'M' )
  60. #endif /* !ID_FILM */
  61.  
  62. /* CAT CELL, a single IFF FILM frame (bitmap and sound) */
  63. #ifndef ID_CELL
  64. #define ID_CELL MAKE_ID( 'C', 'E', 'L', 'L' )
  65. #endif /* !ID_CELL */
  66.  
  67. /* body, used by CELLs ILBM and 8SVX */
  68. #ifndef ID_BODY
  69. #define ID_BODY MAKE_ID( 'B', 'O', 'D', 'Y' )
  70. #endif /* !ID_BODY */
  71.  
  72. /* IFF ILBM */
  73. #ifndef ID_ILBM
  74. #define ID_ILBM MAKE_ID( 'I', 'L', 'B', 'M' )
  75. #endif /* !ID_ILBM */
  76.  
  77. /* ILBM BMHD (bitmap header) */
  78. #ifndef ID_BMHD
  79. #define ID_BMHD MAKE_ID( 'B', 'M', 'H', 'D' )
  80. #endif /* !ID_BMHD */
  81.  
  82. /* ILBM CMAP (color map) */
  83. #ifndef ID_CMAP
  84. #define ID_CMAP MAKE_ID( 'C', 'M', 'A', 'P' )
  85. #endif /* !ID_CMAP */
  86.  
  87. /* ILBM CAMG (view mode id) */
  88. #ifndef ID_CAMG
  89. #define ID_CAMG MAKE_ID( 'C', 'A', 'M', 'G' )
  90. #endif /* !ID_CMAP */
  91.  
  92. /* IFF 8SVX */
  93. #ifndef ID_8SVX
  94. #define ID_8SVX MAKE_ID( '8', 'S', 'V', 'X' )
  95. #endif /* !ID_8SVX */
  96.  
  97. /* 8SVX VHDR (VoiceHeader) */
  98. #ifndef ID_VHDR
  99. #define ID_VHDR MAKE_ID( 'V', 'H', 'D', 'R' )
  100. #endif /* !ID_VHDR */
  101.  
  102. /* 8SVX CHAN (left/right/stereo channel) */
  103. #ifndef ID_CHAN
  104. #define CHAN_RIGHT  (4L)
  105. #define CHAN_LEFT   (2L)
  106. #define CHAN_STEREO (6L)  /* CHAN_RIGHT + CHAN_LEFT */
  107.  
  108. #define ID_CHAN MAKE_ID( 'C', 'H', 'A', 'N' )
  109. #endif /* !ID_CHAN */
  110.  
  111. /*****************************************************************************/
  112.  
  113. /* from <iffp/ilbm.h>*/
  114. /* BMHD flags */
  115.  
  116. /* Advisory that 8 significant bits-per-gun have been stored in CMAP
  117.  * i.e. that the CMAP is definitely not 4-bit values shifted left.
  118.  * This bit will disable nibble examination by color loading routine.
  119.  */
  120. #define BMHDB_CMAPOK (7U)
  121. #define BMHDF_CMAPOK (1U << BMHDB_CMAPOK)
  122.  
  123. /*****************************************************************************/
  124.  
  125. extern struct ExecBase  *SysBase;
  126. extern struct Library   *DOSBase;
  127.        struct Library   *IFFParseBase;
  128.        struct Library   *IconBase;
  129.        struct Library   *GfxBase;
  130.        struct Library   *IntuitionBase;
  131.        struct Library   *DataTypesBase;
  132.  
  133. /*****************************************************************************/
  134.  
  135.  
  136. #define TEMPLATE "NAME/A,"                           \
  137.                  "MOVIE/S,"                          \
  138.                  "STARTFRAME/K/N,"                   \
  139.                  "STOPFRAME/K/N,"                    \
  140.                  "SKIPFRAMES/K/N,"                   \
  141.                  "IFFFILM=FILM/K,"                   \
  142.                  "CLIPIFFFILM=CLIPFILM/S,"           \
  143.                  "CLIPIFFFILMUNIT=CLIPFILMUNIT/K/N," \
  144.                  "PICTUREPERFRAME/S,"                \
  145.                  "SAMPLEPERFRAME=SPF/S,"             \
  146.                  "GLOBALSAMPLE/S"
  147.  
  148. #define OPT_NAME             (0)
  149. #define OPT_MOVIE            (1)
  150. #define OPT_STARTFRAME       (2)
  151. #define OPT_STOPFRAME        (3)
  152. #define OPT_SKIPFRAMES       (4)
  153. #define OPT_IFFFILM          (5)
  154. #define OPT_CLIPIFFFILM      (6)
  155. #define OPT_CLIPIFFFILMUNIT  (7)
  156. #define OPT_PICTUREPERFRAME  (8)
  157. #define OPT_SAMPLEPERFRAME   (9)
  158. #define OPT_GLOBALSAMPLE    (10)
  159. #define NUM_OPTS            (11)
  160.  
  161. /*****************************************************************************/
  162.  
  163.  
  164. /* prototypes */
  165. long              main( void );
  166.  
  167. struct IFFHandle *OpenIFFFile( STRPTR, ULONG );
  168. BOOL              CloseIFFFile( struct IFFHandle * );
  169.  
  170. struct IFFHandle *OpenIFFClipboard( LONG );
  171. void              CloseIFFClipboard( struct IFFHandle * );
  172.  
  173. LONG              StartIFFFilm( struct IFFHandle *, struct BitMapHeader *, ULONG, struct ColorRegister *, ULONG, struct VoiceHeader * );
  174. void              EndIFFFilm( struct IFFHandle * );
  175. LONG              WriteIFFFilmCell( struct IFFHandle *, struct BitMapHeader *, struct BitMap *, BYTE *, ULONG );
  176. LONG              Put8SVXBody( struct IFFHandle *, BYTE *, ULONG );
  177. LONG              PutILBMBody( struct IFFHandle *, struct BitMap *, struct BitMapHeader * );
  178.  
  179. ULONG             SaveDTObject( Object *, struct Window *, struct Requester *, STRPTR, ULONG, struct TagItem * );
  180. void              SaveSample( STRPTR, BYTE *, ULONG, ULONG, ULONG );
  181.  
  182. void              FillColorRegisters( struct ColorRegister *, ULONG *, ULONG );
  183. void              CopyBitMap( struct BitMap *, struct BitMap * );
  184. void              mysprintf( STRPTR, STRPTR , ... );
  185.  
  186. /*****************************************************************************/
  187.  
  188. /* IFF errors to DOS errors */
  189. LONG ifferr2doserr[] =
  190. {
  191.   0L,                         /* End of file (not an error).                  */
  192.   0L,                         /* End of context (not an error).               */
  193.   DTERROR_INVALID_DATA,       /* No lexical scope.                            */
  194.   ERROR_NO_FREE_STORE,        /* Insufficient memory.                         */
  195.   ERROR_SEEK_ERROR,           /* Stream read error.                           */
  196.   ERROR_SEEK_ERROR,           /* Stream write error.                          */
  197.   ERROR_SEEK_ERROR,           /* Stream seek error.                           */
  198.   DTERROR_INVALID_DATA,       /* File is corrupt.                             */
  199.   DTERROR_INVALID_DATA,       /* IFF syntax error.                            */
  200.   ERROR_OBJECT_WRONG_TYPE,    /* Not an IFF file.                             */
  201.   ERROR_REQUIRED_ARG_MISSING, /* Required call-back hook missing.             */
  202.   (3000L),                    /* Return to client.  You should never see this */
  203. };
  204.  
  205. /*****************************************************************************/
  206.  
  207.  
  208. long main( void )
  209. {
  210.     /* Argument parsing variables */
  211.     LONG                    options[ NUM_OPTS ];
  212.     struct RDArgs          *rdargs;
  213.     LONG                    error = 0L;
  214.  
  215.     memset( options, 0, sizeof( options ) );
  216.  
  217.     IFFParseBase     = OpenLibrary( "iffparse.library",  39UL );
  218.     IconBase         = OpenLibrary( "icon.library",      39UL );
  219.     GfxBase          = OpenLibrary( "graphics.library",  39UL );
  220.     IntuitionBase    = OpenLibrary( "intuition.library", 39UL );
  221.     DataTypesBase    = OpenLibrary( "datatypes.library", 39UL );
  222.  
  223.     if( IFFParseBase && IconBase && GfxBase && IntuitionBase && DataTypesBase )
  224.     {
  225.       if( rdargs = ReadArgs( TEMPLATE, options, NULL ) )
  226.       {
  227.         STRPTR              filepart    = FilePart( (STRPTR)options[ OPT_NAME ] );
  228.         ULONG               startframe  = 1UL,  /* start at this frame                  */
  229.                             stopframe   = ~0UL, /* stop at this frame                   */
  230.                             skipframes  = 1UL;  /* skip n frames during scan            */
  231.  
  232.         struct IFFHandle   *ifffilm     = NULL, /* IFF FILM output stream (file)        */
  233.                            *clipifffilm = NULL; /* IFF FILM output stream (clipboard)   */
  234.  
  235.         Object             *o;                  /* anim/movie object */
  236.  
  237.         if( options[ OPT_STARTFRAME ] )
  238.         {
  239.           startframe = *((LONG *)options[ OPT_STARTFRAME ]);
  240.  
  241.           if( startframe < 1UL )
  242.           {
  243.             startframe = 1UL;
  244.           }
  245.         }
  246.  
  247.         if( options[ OPT_STOPFRAME ] )
  248.         {
  249.           stopframe = *((LONG *)options[ OPT_STOPFRAME ]);
  250.  
  251.           if( stopframe < 1UL )
  252.           {
  253.             stopframe = 1UL;
  254.           }
  255.         }
  256.  
  257.         if( options[ OPT_SKIPFRAMES ] )
  258.         {
  259.           skipframes = *((LONG *)options[ OPT_SKIPFRAMES ]);
  260.  
  261.           if( skipframes < 1UL )
  262.           {
  263.             skipframes = 1UL;
  264.           }
  265.         }
  266.  
  267.         /* Open the animation/movie object */
  268.         if( o = NewDTObject( (APTR)options[ OPT_NAME ],
  269.  
  270.                              /* We will only accept sound DataTypes */
  271.                              DTA_GroupID,      ((options[ OPT_MOVIE ])?(GID_MOVIE):(GID_ANIMATION)),
  272.  
  273.                              /* No more attributes */
  274.                              TAG_DONE ) )
  275.         {
  276.           struct gpLayout         gpl;
  277.  
  278.           /* Base information */
  279.           STRPTR                  objname;
  280.  
  281.           /* Animation related */
  282.           ULONG                   animwidth,              /* width of animation */
  283.                                   animheight,             /* height of animation */
  284.                                   animdepth;              /* depth of animation */
  285.           ULONG                   anumframes = 0UL;       /* number of frames in animation */
  286.           ULONG                   afps = 0UL;
  287.  
  288.           /* Anim frame loading */
  289.           struct adtFrame         alf;                    /* method msg for ADTM_LOADFRAME */
  290.           ULONG                   timestamp;              /* timestamp to load */
  291.  
  292.           /* Animation frame picture related */
  293.           ULONG                   amodeid;                /* mode id of animation */
  294.           struct BitMapHeader    *abmh;                   /* bitmapheader of animation */
  295.           ULONG                   anumcolors;             /* number of colors in animation */
  296.           ULONG                  *acregs;                 /* ADTA_CRegs */
  297.           struct ColorRegister   *acm;                    /* ADTA_ColorRegisters struct ColorRegister array */
  298.  
  299.           TEXT                    picturefilename[ 512 ]; /* buffer for filename when writing */
  300.  
  301.           /* Anim frame sample related */
  302.           BYTE                   *asample;
  303.           ULONG                   asamplelength = 0UL;
  304.  
  305.           ULONG                   aperiod;
  306.           ULONG                   acycles;
  307.  
  308.           TEXT                    samplefilename[ 512 ];
  309.  
  310.           /* Sample build from all samples */
  311. #define GLOBALSAMPLESIZE (100000UL)
  312.           BYTE                   *globalsample        = NULL;
  313.           ULONG                   globalsampleoffset  = 0UL;
  314.  
  315.           if( options[ OPT_GLOBALSAMPLE ] )
  316.           {
  317.             globalsample = (BYTE *)AllocVec( GLOBALSAMPLESIZE, MEMF_PUBLIC );
  318.           }
  319.  
  320.           /* Get information about the object */
  321.           if( GetDTAttrs( o, DTA_ObjName,          (&objname),
  322.                              ADTA_Width,           (&animwidth),
  323.                              ADTA_Height,          (&animheight),
  324.                              ADTA_Depth,           (&animdepth),
  325.                              ADTA_Frames,          (&anumframes),
  326.                              ADTA_FramesPerSecond, (&afps),
  327.                              ADTA_ModeID,          (&amodeid),
  328.                              PDTA_BitMapHeader,    (&abmh),
  329.                              ADTA_NumColors,       (&anumcolors),
  330.                              ADTA_CRegs,           (&acregs),
  331.                              ADTA_ColorRegisters,  (&acm),
  332.                              ADTA_Cycles,          (&acycles),
  333.                              ADTA_Period,          (&aperiod),
  334.                              ADTA_Sample,          (&asample),
  335.                              ADTA_SampleLength,    (&asamplelength),
  336.                              TAG_DONE ) != 15UL )
  337.           {
  338.             Printf( "*** warning: not enough attributes to get\n" );
  339.           }
  340.  
  341.           /* Sound available ? */
  342.           if( asamplelength && aperiod )
  343.           {
  344.             struct VoiceHeader vh;
  345.  
  346.             vh . vh_OneShotHiSamples     = asamplelength;
  347.             vh . vh_RepeatHiSamples      = 0UL;
  348.             vh . vh_SamplesPerHiCycle    = 0UL;
  349.             vh . vh_SamplesPerSec        = ((SysBase -> ex_EClockFrequency) * 5UL) / aperiod;
  350.             vh . vh_Octaves              = 1UL;
  351.             vh . vh_Compression          = CMP_NONE;
  352.             vh . vh_Volume               = 0x10000UL; /* maximum volume */
  353.  
  354.             if( options[ OPT_IFFFILM ] )
  355.             {
  356.               if( ifffilm = OpenIFFFile( (STRPTR)options[ OPT_IFFFILM ], MODE_NEWFILE ) )
  357.               {
  358.                 if( error = StartIFFFilm( ifffilm, abmh, amodeid, acm, anumcolors, (&vh) ) )
  359.                 {
  360.                   Printf( "error while writing IFF FILM to file%ld\n", error );
  361.  
  362.                   CloseIFFFile( ifffilm );
  363.                   ifffilm = NULL;
  364.                 }
  365.                 else
  366.                 {
  367.                   Printf( "writing IFF FILM stream to file %s\n", (STRPTR)options[ OPT_IFFFILM ] );
  368.                 }
  369.               }
  370.               else
  371.               {
  372.                 Printf( "can't open iff file\n" );
  373.                 error = IoErr();
  374.               }
  375.             }
  376.  
  377.             if( options[ OPT_CLIPIFFFILM ] )
  378.             {
  379.               LONG unit;
  380.  
  381.               if( options[ OPT_CLIPIFFFILMUNIT ] )
  382.               {
  383.                 unit = *((LONG *)options[ OPT_CLIPIFFFILMUNIT ]);
  384.               }
  385.               else
  386.               {
  387.                 unit = PRIMARY_CLIP;
  388.               }
  389.  
  390.               if( clipifffilm = OpenIFFClipboard( unit ) )
  391.               {
  392.                 if( error = StartIFFFilm( clipifffilm, abmh, amodeid, acm, anumcolors, (&vh) ) )
  393.                 {
  394.                   Printf( "error while writing IFF FILM to clipboard %ld\n", error );
  395.  
  396.                   CloseIFFClipboard( clipifffilm );
  397.                   clipifffilm = NULL;
  398.                 }
  399.                 else
  400.                 {
  401.                   Printf( "writing IFF FILM stream to clipboard unit %ld\n", unit );
  402.                 }
  403.               }
  404.               else
  405.               {
  406.                 Printf( "can't open iff clipboard\n" );
  407.                 error = IoErr();
  408.               }
  409.             }
  410.           }
  411.           else
  412.           {
  413.             if( options[ OPT_IFFFILM ] || options[ OPT_CLIPIFFFILM ] )
  414.             {
  415.               Printf( "can't create IFF FILM stream because sound is missing\n" );
  416.               error = ERROR_OBJECT_WRONG_TYPE;
  417.             }
  418.           }
  419.  
  420.           /* Display any information we obtained */
  421.           if( objname )
  422.           {
  423.             Printf( "Name: \"%s\"\n", objname );
  424.           }
  425.  
  426.           /* Print info... */
  427.           Printf( "width %lu height %lu depth %lu frames %lu\n"
  428.                   "FramesPerSecond %lu modeid %lx colors %lu\n"
  429.                   "sample %lx samplelength %lu cycles %lu period %lu\n",
  430.                    animwidth, animheight, animdepth, anumframes,
  431.                    afps, amodeid, anumcolors,
  432.                    asample, asamplelength, acycles, aperiod );
  433.  
  434.           /* "Layout" animation (for those anim classes which need this,
  435.            * __NOT__ recommened)
  436.            */
  437.           gpl . MethodID    = DTM_PROCLAYOUT;
  438.           gpl . gpl_GInfo   = NULL;
  439.           gpl . gpl_Initial = 1L;
  440.  
  441.           DoMethodA( o, (Msg)(&gpl) );
  442.  
  443.           /* Start scan through animation */
  444.           for( timestamp = startframe ; (timestamp < anumframes) && (timestamp <= stopframe) ; timestamp += skipframes )
  445.           {
  446.             /* On error break */
  447.             if( error )
  448.             {
  449.               break;
  450.             }
  451.  
  452.             /* Check for CTRL_C signal... */
  453.             if( SetSignal( 0UL, 0UL ) & SIGBREAKF_CTRL_C )
  454.             {
  455.               error = ERROR_BREAK;
  456.  
  457.               break;
  458.             }
  459.  
  460.             /* reset method msg */
  461.             memset( (void *)(&alf), 0, sizeof( struct adtFrame ) );
  462.  
  463.             /* load frame */
  464.             alf . MethodID = ADTM_LOADFRAME;
  465.             alf . alf_TimeStamp = timestamp;
  466.             alf . alf_Frame     = timestamp;
  467.             DoMethodA( o, (Msg)(&alf) );
  468.  
  469.             /* print frame contents */
  470.             Printf( "frame: timestamp %lu frame %lu duration %lu bitmap %lx cmap %lx sample %lx len %lu period %lu\n",
  471.                     timestamp,
  472.                     (alf . alf_Frame),
  473.                     (alf . alf_Duration),
  474.                     (alf . alf_BitMap),
  475.                     (alf . alf_CMap),
  476.                     (alf . alf_Sample),
  477.                     (alf . alf_SampleLength),
  478.                     (alf . alf_Period) );
  479.  
  480.             /* handle picture data */
  481.             if( abmh && (alf . alf_BitMap) && options[ OPT_PICTUREPERFRAME ] )
  482.             {
  483.               ULONG          framewidth,
  484.                              frameheight,
  485.                              framedepth;
  486.               struct BitMap *bm;
  487.  
  488.               /* bitmap dimensions may not match ADTA_(Width|Height|Depth) dimentions */
  489.               framewidth  = GetBitMapAttr( (alf . alf_BitMap), BMA_WIDTH  );
  490.               frameheight = GetBitMapAttr( (alf . alf_BitMap), BMA_HEIGHT );
  491.               framedepth  = GetBitMapAttr( (alf . alf_BitMap), BMA_DEPTH  );
  492.  
  493.               /* Here we must allocate a temp chip mem bitmap because animation frames can be
  494.                * outside CHIP-MEM and picture.datatype cannot deal with non-chip-mem bitmaps...
  495.                */
  496.               if( bm = AllocBitMap( framewidth, frameheight, framedepth, 0UL, (alf . alf_BitMap) ) )
  497.               {
  498.                 Object *po;
  499.  
  500.                 /* Copy bitmap */
  501.                 CopyBitMap( bm, (alf . alf_BitMap) );
  502.  
  503.                 /* Create picture object and set it up manually (e.g. DTST_RAM) */
  504.                 if( po = NewDTObject( NULL,
  505.                                       DTA_SourceType, DTST_RAM,
  506.                                       DTA_GroupID,    GID_PICTURE,
  507.                                       TAG_DONE ) )
  508.                 {
  509.                   struct BitMapHeader *pbmh;
  510.  
  511.                   if( GetDTAttrs( po, PDTA_BitMapHeader, (&pbmh), TAG_DONE ) )
  512.                   {
  513.                     if( pbmh )
  514.                     {
  515.                       ULONG                *pcregs;
  516.                       struct ColorRegister *pcm;
  517.                       ULONG                 numcolors = (1UL << animdepth), /* note that numcolors
  518.                                                                              * may not match ADTA_NumColors
  519.                                                                              */
  520.                                             allocated_numcolors;
  521.  
  522.                       /* copy bitmapheader (RAW) from animation bmh... */
  523.                       *pbmh = *abmh;
  524.  
  525.                       /* ...and fill in attributes which may be different */
  526.                       pbmh -> bmh_Width  = framewidth;
  527.                       pbmh -> bmh_Height = frameheight;
  528.                       pbmh -> bmh_Depth  = framedepth;
  529.  
  530.                       /* we're writing a full palette, set this flag (currently NOP, but...) */
  531.                       pbmh -> bmh_Pad    = BMHDF_CMAPOK; /* also known as bmh_Flags */
  532.  
  533.                       /* Set screen mode id,
  534.                        * our bitmap and
  535.                        * the requested number of colors...
  536.                        */
  537.                       SetDTAttrs( po, NULL, NULL,
  538.                                   PDTA_ModeID,      amodeid,
  539.                                   PDTA_NumColors,   numcolors,
  540.                                   PDTA_BitMap,      bm,
  541.                                   TAG_DONE );
  542.  
  543.                       /* Get color tables (pcregs, pcm) and the allocated number of colors */
  544.                       if( GetDTAttrs( po, PDTA_CRegs,          (&pcregs),
  545.                                           PDTA_ColorRegisters, (&pcm),
  546.                                           PDTA_NumColors,      (&allocated_numcolors),
  547.                                           TAG_DONE ) == 3UL )
  548.                       {
  549.                         /* Success ? */
  550.                         if( pcregs && pcm )
  551.                         {
  552.                           ULONG i;
  553.  
  554.                           if( allocated_numcolors != numcolors )
  555.                           {
  556.                             Printf( "allocated_numcolors %lu != numcolors %lu\n", allocated_numcolors, numcolors );
  557.                           }
  558.  
  559.                           /* get colors (either from frame's colormap or from animation's palette */
  560.                           if( alf . alf_CMap )
  561.                           {
  562.                             GetRGB32( (alf . alf_CMap), 0UL, (allocated_numcolors - 1UL), pcregs );
  563.                           }
  564.                           else
  565.                           {
  566.                             for( i = 0UL ; i < allocated_numcolors ; i++ )
  567.                             {
  568.                               pcregs[ ((i * 3) + 0) ] = acregs[ ((i * 3) + 0) ]; /* copy r, */
  569.                               pcregs[ ((i * 3) + 1) ] = acregs[ ((i * 3) + 1) ]; /*      g, */
  570.                               pcregs[ ((i * 3) + 2) ] = acregs[ ((i * 3) + 2) ]; /*      b  */
  571.                             }
  572.                           }
  573.  
  574.                           /* copy cregs to colorregisters */
  575.                           FillColorRegisters( pcm, acregs, allocated_numcolors );
  576.  
  577.                           mysprintf( picturefilename, "%s_picture_%05.5lu.ilbm", filepart, timestamp );
  578.                           Printf( "saving picture: \"%s\"\n", picturefilename );
  579.                           SaveDTObject( po, NULL, NULL, picturefilename, DTWM_IFF, NULL );
  580.                         }
  581.                         else
  582.                         {
  583.                           Printf( "picture object mem err (no color tables)\n" );
  584.                           error = ERROR_NO_FREE_STORE;
  585.                         }
  586.                       }
  587.                       else
  588.                       {
  589.                         /* can't get required args from object */
  590.                         error = ERROR_OBJECT_WRONG_TYPE;
  591.                       }
  592.  
  593.                       /* picture.datatype object will free the bitmap */
  594.                       bm = NULL;
  595.                     }
  596.                     else
  597.                     {
  598.                       Printf( "can't get bitmapheader\n" );
  599.                       error = ERROR_NO_FREE_STORE;
  600.                     }
  601.                   }
  602.                   else
  603.                   {
  604.                     /* can't get required args from object */
  605.                     Printf( "can't get PDTA_BitMapHeader\n" );
  606.                     error = ERROR_OBJECT_WRONG_TYPE;
  607.                   }
  608.  
  609.                   /* Get rid of the picture object */
  610.                   DisposeDTObject( po );
  611.                 }
  612.                 else
  613.                 {
  614.                   Printf( "can't create picture object\n" );
  615.                   error = IoErr();
  616.                 }
  617.  
  618.                 /* free temp bitmap */
  619.                 FreeBitMap( bm );
  620.               }
  621.               else
  622.               {
  623.                 Printf( "can't alloc frame bitmap\n" );
  624.                 error = ERROR_NO_FREE_STORE;
  625.               }
  626.             }
  627.  
  628.             /* handle sound/sample data */
  629.             if( alf . alf_Sample )
  630.             {
  631.               if( options[ OPT_SAMPLEPERFRAME ] )
  632.               {
  633.                 mysprintf( samplefilename, "%s_sample_%05.5lu.8svx", filepart, timestamp );
  634.                 Printf( "saving sample : \"%s\"\n", samplefilename );
  635.                 SaveSample( samplefilename, (alf . alf_Sample), (alf . alf_SampleLength), (alf . alf_Period), acycles );
  636.               }
  637.  
  638.               if( globalsample )
  639.               {
  640.                 if( globalsampleoffset < (GLOBALSAMPLESIZE - (1000UL + (alf . alf_SampleLength))) )
  641.                 {
  642.                   CopyMem( (alf . alf_Sample), (globalsample + globalsampleoffset), (alf . alf_SampleLength) );
  643.                   globalsampleoffset += alf . alf_SampleLength;
  644.                 }
  645.                 else
  646.                 {
  647.                   Printf( "global sample buffer overflow\n" );
  648.                   error = ERROR_BUFFER_OVERFLOW;
  649.                 }
  650.               }
  651.             }
  652.  
  653.             if( ifffilm )
  654.             {
  655.               if( error = WriteIFFFilmCell( ifffilm, abmh, (alf . alf_BitMap), (alf . alf_Sample), (alf . alf_SampleLength) ) )
  656.               {
  657.                 Printf( "error while writing IFF FILM, aborted\n" );
  658.                 EndIFFFilm( ifffilm );
  659.                 CloseIFFFile( ifffilm );
  660.                 ifffilm = NULL;
  661.               }
  662.             }
  663.  
  664.             if( clipifffilm )
  665.             {
  666.               if( error = WriteIFFFilmCell( clipifffilm, abmh, (alf . alf_BitMap), (alf . alf_Sample), (alf . alf_SampleLength) ) )
  667.               {
  668.                 Printf( "error while writing IFF FILM to clipboard, aborted\n" );
  669.                 EndIFFFilm( clipifffilm );
  670.                 CloseIFFClipboard( clipifffilm );
  671.                 clipifffilm = NULL;
  672.               }
  673.             }
  674.  
  675.             alf . MethodID = ADTM_UNLOADFRAME;
  676.             DoMethodA( o, (Msg)(&alf) );
  677.           }
  678.  
  679.           /* Get rid of the anim/movie object */
  680.           DisposeDTObject( o );
  681.  
  682.           if( globalsample )
  683.           {
  684.             mysprintf( samplefilename, "%s_sample_global.8svx", filepart );
  685.             SaveSample( samplefilename, globalsample, globalsampleoffset, aperiod, acycles );
  686.  
  687.             FreeVec( globalsample );
  688.           }
  689.  
  690.           if( ifffilm )
  691.           {
  692.             EndIFFFilm( ifffilm );
  693.             CloseIFFFile( ifffilm );
  694.           }
  695.  
  696.           if( clipifffilm )
  697.           {
  698.             EndIFFFilm( clipifffilm );
  699.             CloseIFFClipboard( clipifffilm );
  700.           }
  701.         }
  702.         else
  703.         {
  704.           error = IoErr();
  705.         }
  706.  
  707.         /* Free the allocated memory after ReadArgs */
  708.         FreeArgs( rdargs );
  709.       }
  710.       else
  711.       {
  712.         /* ReadArgs failed */
  713.         error = IoErr();
  714.       }
  715.     }
  716.     else
  717.     {
  718.       /* can't open required libraries */
  719.       error = ERROR_OBJECT_NOT_FOUND;
  720.     }
  721.  
  722.     /* Error ? */
  723.     if( error )
  724.     {
  725.       TEXT errbuff[ 256 ];
  726.  
  727.       /* IFFParse error code ? */
  728.       if( error < 0L )
  729.       {
  730.         /* convert IFFParse error to DOS error */
  731.         error = ifferr2doserr[ -error - 1 ];
  732.       }
  733.  
  734.       if( error >= DTERROR_UNKNOWN_DATATYPE )
  735.       {
  736.         mysprintf( errbuff, GetDTString( error ), "file" );
  737.       }
  738.       else
  739.       {
  740.         Fault( error, NULL, errbuff, sizeof( errbuff ) );
  741.       }
  742.  
  743.       Printf( "dumpdtanim: %s\n", errbuff );
  744.     }
  745.  
  746.     CloseLibrary( DataTypesBase );
  747.     CloseLibrary( IntuitionBase );
  748.     CloseLibrary( GfxBase );
  749.     CloseLibrary( IconBase );
  750.     CloseLibrary( IFFParseBase );
  751.  
  752.     SetIoErr( error );
  753.  
  754.     return( ((error)?(RETURN_ERROR):(RETURN_OK)) );
  755. }
  756.  
  757.  
  758. struct IFFHandle *OpenIFFFile( STRPTR file, ULONG mode )
  759. {
  760.     struct IFFHandle *iff;
  761.     LONG              ioerr;
  762.  
  763.     if( file && mode )
  764.     {
  765.       if( iff = AllocIFF() )
  766.       {
  767.         /* Set up IFF_File for file I/O. */
  768.         if( iff -> iff_Stream = (ULONG)Open( file, mode ) )
  769.         {
  770.           InitIFFasDOS( iff );
  771.  
  772.           return( iff );
  773.         }
  774.         else
  775.         {
  776.           /* Open failed */
  777.           ioerr = IoErr();
  778.         }
  779.  
  780.         FreeIFF( iff );
  781.       }
  782.       else
  783.       {
  784.         /* AllocIFF failed */
  785.         ioerr = ERROR_NO_FREE_STORE;
  786.       }
  787.     }
  788.     else
  789.     {
  790.       /* wrong function args */
  791.       ioerr = ERROR_REQUIRED_ARG_MISSING;
  792.     }
  793.  
  794.     SetIoErr( ioerr );
  795.  
  796.     return( NULL );
  797. }
  798.  
  799.  
  800. BOOL CloseIFFFile( struct IFFHandle *iff )
  801. {
  802.     BOOL success = FALSE;
  803.  
  804.     if( iff )
  805.     {
  806.       success = Close( (BPTR)(iff -> iff_Stream) );
  807.  
  808.       FreeIFF( iff );
  809.     }
  810.  
  811.     return( success );
  812. }
  813.  
  814.  
  815. struct IFFHandle *OpenIFFClipboard( LONG unit )
  816. {
  817.     struct IFFHandle *iff;
  818.     LONG              ioerr;
  819.  
  820.     if( iff = AllocIFF() )
  821.     {
  822.       /* Set up IFF_File for clipboard I/O. */
  823.       if( iff -> iff_Stream = (ULONG)OpenClipboard( unit ) )
  824.       {
  825.         InitIFFasClip( iff );
  826.  
  827.         return( iff );
  828.       }
  829.       else
  830.       {
  831.         /* couldn't open clipboard */
  832.         ioerr = DTERROR_COULDNT_OPEN_CLIPBOARD;
  833.       }
  834.  
  835.       FreeIFF( iff );
  836.     }
  837.     else
  838.     {
  839.       /* AllocIFF failed */
  840.       ioerr = ERROR_NO_FREE_STORE;
  841.     }
  842.  
  843.     SetIoErr( ioerr );
  844.  
  845.     return( NULL );
  846. }
  847.  
  848.  
  849. void CloseIFFClipboard( struct IFFHandle *iff )
  850. {
  851.     if( iff )
  852.     {
  853.       CloseClipboard( (struct ClipboardHandle *)(iff -> iff_Stream) );
  854.  
  855.       FreeIFF( iff );
  856.     }
  857. }
  858.  
  859.  
  860. LONG StartIFFFilm( struct IFFHandle *iff, struct BitMapHeader *bmh, ULONG modeid, struct ColorRegister *cm, ULONG numcolors, struct VoiceHeader *vh )
  861. {
  862.     LONG error;
  863.  
  864.     if( !(error = OpenIFF( iff, IFFF_WRITE )) )
  865.     {
  866.       for( ;; ) /* not a loop, used as a jump table */
  867.       {
  868.         if( error = PushChunk( iff, ID_FILM, ID_LIST, IFFSIZE_UNKNOWN ) )
  869.           break;
  870.  
  871.         /* write ILBM props */
  872.         {
  873.           if( error = PushChunk( iff, ID_ILBM, ID_PROP, IFFSIZE_UNKNOWN ) )
  874.             break;
  875.  
  876.           /* write ILBM BMHD (BitMapHeader) */
  877.           {
  878.             if( error = PushChunk( iff, 0UL, ID_BMHD, IFFSIZE_UNKNOWN ) )
  879.              break;
  880.  
  881.             if( WriteChunkBytes( iff, (APTR)bmh, sizeof( struct BitMapHeader ) ) != sizeof( struct BitMapHeader ) )
  882.             {
  883.               error = IFFERR_WRITE;
  884.               break;
  885.             }
  886.  
  887.             if( error = PopChunk( iff ) )
  888.               break;
  889.           }
  890.  
  891.           /* write ILBM CAMG (amiga view mode) */
  892.           {
  893.             if( error = PushChunk( iff, 0UL, ID_CAMG, IFFSIZE_UNKNOWN ) )
  894.              break;
  895.  
  896.             if( WriteChunkBytes( iff, (APTR)(&modeid), sizeof( ULONG ) ) != sizeof( ULONG ) )
  897.             {
  898.               error = IFFERR_WRITE;
  899.               break;
  900.             }
  901.  
  902.             if( error = PopChunk( iff ) )
  903.               break;
  904.           }
  905.  
  906.           /* write ILBM CMAP (global color map) */
  907.           {
  908.             ULONG i;
  909.  
  910.             if( error = PushChunk( iff, 0UL, ID_CMAP, IFFSIZE_UNKNOWN ) )
  911.               break;
  912.  
  913.             for( i = 0UL ; i < numcolors ; i++, cm++ )
  914.             {
  915.               /* Write R, B, G bytes */
  916.               if( WriteChunkBytes( iff, (APTR)cm, 3UL ) != 3UL )
  917.               {
  918.                 error = IFFERR_WRITE;
  919.                 break;
  920.               }
  921.             }
  922.  
  923.             /* any error in loop above ? */
  924.             if( error )
  925.               break;
  926.  
  927.             if( error = PopChunk( iff ) )
  928.               break;
  929.           }
  930.  
  931.           if( error = PopChunk( iff ) )
  932.             break;
  933.         }
  934.  
  935.         /* write 8SVX props */
  936.         {
  937.           if( error = PushChunk( iff, ID_8SVX, ID_PROP, IFFSIZE_UNKNOWN ) )
  938.             break;
  939.  
  940.           {
  941.             /* write 8SVX VHDR (VoiceHeader) */
  942.             {
  943.               if( error = PushChunk( iff, 0UL, ID_VHDR, IFFSIZE_UNKNOWN ) )
  944.                 break;
  945.  
  946.               if( WriteChunkBytes( iff, (APTR)vh, sizeof( struct VoiceHeader ) ) != sizeof( struct VoiceHeader ) )
  947.               {
  948.                 error = IFFERR_WRITE;
  949.                 break;
  950.               }
  951.  
  952.               if( error = PopChunk( iff ) )
  953.                 break;
  954.             }
  955.           }
  956.           
  957.           /* a 8SVX CHAN chunk is missing here (animation.datatype does currently not support stereo sound) */
  958.  
  959.           if( error = PopChunk( iff ) )
  960.             break;
  961.         }
  962.  
  963.         break; /* end of jump table */
  964.       }
  965.  
  966.       /* All headers written successfully ? */
  967.       if( error == 0L )
  968.       {
  969.         /* Success ! */
  970.         return( 0L );
  971.       }
  972.  
  973.       CloseIFF( iff );
  974.     }
  975.  
  976.     return( error );
  977. }
  978.  
  979.  
  980. void EndIFFFilm( struct IFFHandle *iff )
  981. {
  982.     if( iff )
  983.     {
  984.       LONG error;
  985.  
  986.       if( error = PopChunk( iff ) )
  987.       {
  988.         Printf( "error while popping IFF FILM LIST %ld\n", error );
  989.       }
  990.  
  991.       CloseIFF( iff );
  992.  
  993.       Printf( "IFF FILM sucessfully created\n" );
  994.     }
  995.     else
  996.     {
  997.       Printf( "no iff\n" );
  998.     }
  999. }
  1000.  
  1001.  
  1002. LONG WriteIFFFilmCell( struct IFFHandle *iff, struct BitMapHeader *bmh, struct BitMap *bm, BYTE *sample, ULONG samplelength )
  1003. {
  1004.     LONG error;
  1005.  
  1006.     for( ;; ) /* not a loop, used as a jump-table */
  1007.     {
  1008.       if( error = PushChunk( iff, ID_CELL, ID_CAT, IFFSIZE_UNKNOWN ) )
  1009.         break;
  1010.  
  1011.       /* write FORM ILBM */
  1012.       {
  1013.         if( error = PushChunk( iff, ID_ILBM, ID_FORM, IFFSIZE_UNKNOWN ) )
  1014.           break;
  1015.  
  1016.         /* Write ILBM BODY */
  1017.         if( error = PutILBMBody( iff, bm, bmh ) )
  1018.           break;
  1019.  
  1020.         if( error = PopChunk( iff ) )
  1021.           break;
  1022.       }
  1023.  
  1024.       /* write FORM 8SVX */
  1025.       {
  1026.         if( error = PushChunk( iff, ID_8SVX, ID_FORM, IFFSIZE_UNKNOWN ) )
  1027.           break;
  1028.  
  1029.         /* Write 8SVX BODY */
  1030.         if( error = Put8SVXBody( iff, sample, samplelength ) )
  1031.           break;
  1032.  
  1033.         if( error = PopChunk( iff ) )
  1034.           break;
  1035.       }
  1036.  
  1037.       if( error = PopChunk( iff ) )
  1038.         break;
  1039.  
  1040.       break; /* end of jump-table */
  1041.     }
  1042.  
  1043.     return( error );
  1044. }
  1045.  
  1046.  
  1047. LONG Put8SVXBody( struct IFFHandle *iff, BYTE *sample, ULONG samplelength )
  1048. {
  1049.     LONG error;
  1050.  
  1051.     /* Write out a BODY chunk header */
  1052.     if( error = PushChunk( iff, NULL, ID_BODY, IFFSIZE_UNKNOWN ) )
  1053.       return( error );
  1054.  
  1055.     if( WriteChunkBytes( iff, sample, samplelength ) != samplelength )
  1056.       return( IFFERR_WRITE );
  1057.  
  1058.     /* Finish the chunk */
  1059.     error = PopChunk( iff );
  1060.  
  1061.     return( error );
  1062. }
  1063.  
  1064.  
  1065. /*****************************************************************************/
  1066.  
  1067. /* from IFF example code ("iffp/ilbm.h") */
  1068. #define RowBytes( w )     ((((w) + 15) >> 4) << 1)
  1069. #define RowBits( w )      ((((w) + 15) >> 4) << 4)
  1070.  
  1071.  
  1072. LONG PutILBMBody( struct IFFHandle *iff, struct BitMap *bitmap, struct BitMapHeader *bmh )
  1073. {
  1074.     LONG     error;
  1075.     LONG     rowBytes        = bitmap -> BytesPerRow;           /* for source modulo only */
  1076.     LONG     FileRowBytes    = RowBytes( (bmh -> bmh_Width) );  /* width to write in bytes */
  1077.     ULONG    planeCnt        = bmh -> bmh_Depth;               /* number of bit planes including mask */
  1078.     ULONG    iPlane,
  1079.              iRow;
  1080.     BYTE    *planes[ 24 ]; /* array of ptrs to planes & mask */
  1081.  
  1082.     /* Copy the ptrs to bit & mask planes into local array "planes" */
  1083.     for( iPlane = 0 ; iPlane < planeCnt; iPlane++ )
  1084.        planes[ iPlane ] = (BYTE *)(bitmap -> Planes[ iPlane ]);
  1085.  
  1086.     /* Write out a BODY chunk header */
  1087.     if( error = PushChunk( iff, NULL, ID_BODY, IFFSIZE_UNKNOWN ) )
  1088.       return( error );
  1089.  
  1090.     /* Write out the BODY contents */
  1091.     for( iRow = bmh -> bmh_Height ; iRow > 0 ; iRow-- )
  1092.     {
  1093.       for( iPlane = 0 ; iPlane < planeCnt ; iPlane++ )
  1094.       {
  1095.         /* Write next row.*/
  1096.         if( WriteChunkBytes( iff, planes[ iPlane ], FileRowBytes ) != FileRowBytes )
  1097.           return( IFFERR_WRITE );
  1098.  
  1099.         planes[ iPlane ] += rowBytes; /* Possibly skipping unused bytes */
  1100.       }
  1101.     }
  1102.  
  1103.     /* Finish the chunk */
  1104.     error = PopChunk( iff );
  1105.  
  1106.     return( error );
  1107. }
  1108.  
  1109.  
  1110. /* save datatypes object with matching icon */
  1111. ULONG SaveDTObject( Object *dto, struct Window *window, struct Requester *requester, STRPTR filename, ULONG mode, struct TagItem *dtw_AttrList )
  1112. {
  1113.     ULONG retval = 0UL;
  1114.  
  1115.     if( dto && filename )
  1116.     {
  1117.       struct DataType *dtn;
  1118.  
  1119.       /* Get the object type */
  1120.       if( GetDTAttrs( dto, DTA_DataType, (&dtn), TAG_DONE ) )
  1121.       {
  1122.         BPTR fh;
  1123.  
  1124.         /* Open new file... */
  1125.         if( fh = Open( filename, MODE_NEWFILE ) )
  1126.         {
  1127.           struct dtWrite dtw;
  1128.           LONG           ioerr;
  1129.  
  1130.           /* Write... */
  1131.           dtw . MethodID       = DTM_WRITE;
  1132.           dtw . dtw_GInfo      = NULL;
  1133.           dtw . dtw_FileHandle = fh;
  1134.           dtw . dtw_Mode       = mode;
  1135.           dtw . dtw_AttrList   = dtw_AttrList;
  1136.  
  1137.           if( retval = DoDTMethodA( dto, window, requester, (Msg)(&dtw) ) )
  1138.           {
  1139.             TEXT               buffer[ 256 ];
  1140.             struct DiskObject *dobj;
  1141.  
  1142.             /* Save IoErr code because following code will clear this */
  1143.             ioerr = IoErr();
  1144.  
  1145.             if( dtn )
  1146.             {
  1147.               /* Get the an icon for the file */
  1148.               mysprintf( buffer, "ENV:Sys/def_%.240s", (dtn -> dtn_Header -> dth_BaseName) );
  1149.  
  1150.               if( (dobj = GetDiskObject( buffer )) == NULL )
  1151.               {
  1152.                 dobj = GetDefDiskObject( WBPROJECT );
  1153.               }
  1154.             }
  1155.             else
  1156.             {
  1157.               dobj = GetDefDiskObject( WBPROJECT );
  1158.             }
  1159.  
  1160.             /* If we have an icon, then write it out */
  1161.             if( dobj )
  1162.             {
  1163.               PutDiskObject( filename, dobj );
  1164.  
  1165.               FreeDiskObject( dobj );
  1166.             }
  1167.           }
  1168.           else
  1169.           {
  1170.             /* Save IoErr code because Close will clear this */
  1171.             ioerr = IoErr();
  1172.           }
  1173.  
  1174.           Close( fh );
  1175.  
  1176.           SetIoErr( ioerr );
  1177.         }
  1178.       }
  1179.       else
  1180.       {
  1181.         /* Can't get DTA_DataType */
  1182.         SetIoErr( ERROR_NO_FREE_STORE );
  1183.       }
  1184.     }
  1185.     else
  1186.     {
  1187.       /* wrong function args */
  1188.       SetIoErr( ERROR_REQUIRED_ARG_MISSING );
  1189.     }
  1190.  
  1191.     return( retval );
  1192. }
  1193.  
  1194.  
  1195. /* save sound sample using a sound.datatype object */
  1196. void SaveSample( STRPTR filename, BYTE *sample, ULONG length, ULONG period, ULONG cycles )
  1197. {
  1198.     Object *so;
  1199.  
  1200.     /* Create sound object and set it up manually (e.g. DTST_RAM) */
  1201.     if( so = NewDTObject( NULL,
  1202.                           DTA_SourceType,    DTST_RAM,
  1203.                           DTA_GroupID,       GID_SOUND,
  1204.                           SDTA_Sample,       sample,
  1205.                           SDTA_SampleLength, MAX( 1UL, length ),
  1206.                           SDTA_Period,       period,
  1207.                           SDTA_Cycles,       (ULONG)MAX( cycles, 1UL ),
  1208.                           TAG_DONE ) )
  1209.     {
  1210.       struct VoiceHeader *vh;
  1211.  
  1212.       /* Set up voiceheader, if possible... */
  1213.       if( GetDTAttrs( so, SDTA_VoiceHeader, (&vh), TAG_DONE ) )
  1214.       {
  1215.         if( vh )
  1216.         {
  1217.           vh -> vh_OneShotHiSamples     = length;
  1218.           vh -> vh_RepeatHiSamples      = 0UL;
  1219.           vh -> vh_SamplesPerHiCycle    = 0UL;
  1220.           vh -> vh_SamplesPerSec        = ((SysBase -> ex_EClockFrequency) * 5UL) / period;
  1221.           vh -> vh_Octaves              = 1UL;
  1222.           vh -> vh_Compression          = CMP_NONE;
  1223.           vh -> vh_Volume               = 0x10000UL;
  1224.         }
  1225.       }
  1226.  
  1227.       /* save the data */
  1228.       SaveDTObject( so, NULL, NULL, filename, DTWM_IFF, NULL );
  1229.  
  1230.       /* The given data (e.g. SDTA_Sample) will be freed by the application */
  1231.       SetDTAttrs( so, NULL, NULL, SDTA_Sample, NULL, TAG_DONE );
  1232.  
  1233.       /* Get rid of the sound object */
  1234.       DisposeDTObject( so );
  1235.     }
  1236. }
  1237.  
  1238.  
  1239. /* copy 32 bits-per-gun cregs table into struct ColorRegister array */
  1240. void FillColorRegisters( struct ColorRegister *cm, ULONG *cregs, ULONG numcolors )
  1241. {
  1242.     if( cm && cregs && numcolors )
  1243.     {
  1244.       ULONG i;
  1245.  
  1246.       for( i = 0UL ; i < numcolors ; i++, cm++ )
  1247.       {
  1248.         /* reduce color information from 32 bits down to 8 bits per r, g, b */
  1249.         cm -> red   = (UBYTE)(cregs[ ((i * 3) + 0) ] >> 24UL);
  1250.         cm -> green = (UBYTE)(cregs[ ((i * 3) + 1) ] >> 24UL);
  1251.         cm -> blue  = (UBYTE)(cregs[ ((i * 3) + 2) ] >> 24UL);
  1252.       }
  1253.     }
  1254. }
  1255.  
  1256.  
  1257. /* Copy bitmap (from fast-mem into chip-mem etc.)
  1258.  * WARNING: This version does __NOT__ work with interleaved bitmaps nor with non-amiga bitmaps
  1259.  */
  1260. void CopyBitMap( struct BitMap *dest, struct BitMap *src )
  1261. {
  1262.     if( dest && src )
  1263.     {
  1264.       ULONG planesize = (ULONG)(dest -> BytesPerRow) * (ULONG)(dest -> Rows);
  1265.       UWORD i;
  1266.  
  1267.       for( i = 0U ; i < (dest -> Depth) ; i++ )
  1268.       {
  1269.         CopyMem( (src -> Planes[ i ]), (dest -> Planes[ i ]), planesize );
  1270.       }
  1271.     }
  1272. }
  1273.  
  1274.  
  1275. void mysprintf( STRPTR buffer, STRPTR fmt, ... )
  1276. {
  1277.     APTR args;
  1278.  
  1279.     args = (APTR)((&fmt) + 1);
  1280.  
  1281.     RawDoFmt( fmt, args, (void (*))"\x16\xc0\x4e\x75", buffer );
  1282. }
  1283.  
  1284.  
  1285.